package model

import (
	"encoding/base64"
	"ginblog/utils/errmsg"
	"golang.org/x/crypto/scrypt"
	"gorm.io/gorm"
	"log"
)

type User struct {
	gorm.Model
	Username string	`gorm:"type:varchar(20);not null "  json:"username" validate:"required,min=4,max=12" label:"用户名"`
	Password string	`gorm:"type:varchar(20);not null "  json:"password" validate:"required,min=6,max=20" label:"密码"`
	//validate里面0是空值，如果设置为0，会直接忽略，所以要+1
	Role int `gorm:"type:int;DEFAULT:2"  json:"role" validate:"required,gte=2" label:"角色"`
}

//查询用户是否存在
func CheckUser(name string) (code int) {
	var users User
	db.Select("id").Where("username = ?",name).First(&users)
	if users.ID>0{
		//有记录
		return errmsg.ERROR_USERNAME_USED
	}
	return errmsg.SUCCSE
}

//更新查询
func CheckUpUser(id int,name string) (code int) {
	var user User
	db.Select("id,username").Where("username=?",name).First(&user)
	if user.ID == uint(id) {
		return errmsg.SUCCSE
	}
	if user.ID>0 {
		return errmsg.ERROR_USERNAME_USED
	}
	return errmsg.SUCCSE
}

//新增用户
func CreateUser(data *User) int {
	//data.Password = ScryptPw(data.Password)
	err := db.Create(&data).Error
	if err != nil {
		return errmsg.ERROR //500
	}
	return errmsg.SUCCSE
}

//查询单个用户
func GetUser(id int) (User,int) {
	var user User
	err = db.Where("ID=?",id).First(&user).Error
	if err!=nil {
		return user,errmsg.ERROR
	}
	return user,errmsg.SUCCSE
}

//查询用户列表
func GetUserList(username string,pageSize int,pageNum int) ([]User,int64) {
	var users []User
	var offset int
	var total int64
	if pageNum==-1 {
		offset = -1
	}else{
		offset = (pageNum-1)*pageSize
	}

	if username == "" {
		err = db.Offset(offset).Limit(pageSize).Find(&users).Count(&total).Error
	}
	err = db.Where("username LIKE?",username+"%").Offset(offset).Limit(pageSize).Find(&users).Count(&total).Error
	if err != nil && err!=gorm.ErrRecordNotFound {
		return nil,0
	}
	return users,total
}

//编辑用户，不能在这里修改，不允许修改，因为涉及到安全
func UpdateUser(id int,data *User) int {
	var user User
	var maps = make(map[string]interface{})
	maps["username"] = data.Username
	maps["role"] = data.Role
	err = db.Model(&user).Where("id=?",id).Updates(maps).Error
	if err != nil {
		return errmsg.ERROR_USERNAME_USED
	}
	return errmsg.SUCCSE
}

//删除
func DeleteUser(id int) int {
	var user User
	err = db.Where("id=?",id).Delete(&user).Error
	if err != nil {
		return errmsg.ERROR
	}
	return errmsg.SUCCSE
}

//密码加密,方法名是事先约定好的，参考官方文档
func (u *User)BeforeSave(tx *gorm.DB) (err error) {
	u.Password = ScryptPw(u.Password)
	return nil
}

func ScryptPw(password string) string {
	//1，声明一个盐
	const KeyLen = 10
	salt := make([]byte,8)
	salt = []byte{12,32,4,6,66,22,222,11}

	HashPw,err := scrypt.Key([]byte(password),salt,16384,8,1,KeyLen)
	if err != nil {
		log.Fatal(err)
	}
	fPw := base64.StdEncoding.EncodeToString(HashPw)
	return fPw
}

//登录验证
func CheckLogin(username,password string) int {
	var user User
	db.Where("username=?",username).First(&user)
	if user.ID == 0 {
		return errmsg.ERROR_USER_NOT_EXIST
	}
	if ScryptPw(password) != user.Password {
		return errmsg.ERROR_PASSWORD_WRONG
	}
	if user.Role!=1{
		return errmsg.ERROR_USER_NO_ROGHT
	}
	return errmsg.SUCCSE
}